Skip to content

[NOMERGE] feat: openapi migration progress#150

Draft
ahmed-n-abdeltwab wants to merge 24 commits intoRocketChat:mainfrom
ahmed-n-abdeltwab:feat/openapi
Draft

[NOMERGE] feat: openapi migration progress#150
ahmed-n-abdeltwab wants to merge 24 commits intoRocketChat:mainfrom
ahmed-n-abdeltwab:feat/openapi

Conversation

@ahmed-n-abdeltwab
Copy link

@ahmed-n-abdeltwab ahmed-n-abdeltwab commented Jul 17, 2025

OpenAPI Migration Progress

This PR tracks the ongoing progress of migrating Rocket.Chat API endpoints to the new OpenAPI pattern with AJV validation and improved documentation. It will be continuously updated to reflect completed and remaining work.

Summary

  • Total endpoints: XX
  • Migrated so far: 186
  • Remaining: XX

👥 Team

  • Ahmed Nasser – Contributor     Buy Me a Coffee
  • Matheus Cardoso – Mentor  
  • Guilherme Gazzo – Co-mentor

🚨 Core API Endpoints

These are 500 endpoints critical for core features and should be migrated first:

Authentication (1 / 9 completed)
Content Management (4 / 11 completed)
Integrations (15 / 15 completed)
Marketplace Apps (0 / 4 completed)
  • apps/public/{app-id}/incoming
  • apps/public/{appId}/templateMessage
  • apps
  • apps/logs
Messaging (8 / 39 completed)
Omnichannel (0 / 154 completed)
  • livechat/users/{type} refactor: Migrate livechat/users endpoints to OpenAPI with AJV validation Rocket.Chat#39584
  • livechat/users/{type}/{_id} refactor: Migrate livechat/users endpoints to OpenAPI with AJV validation Rocket.Chat#39584
  • livechat/agent.info/{rid}/{token}
  • livechat/agent.next/{token}
  • livechat/agents/{agentId}/departments
  • livechat/agents/available
  • livechat/agents/available-for-service-history
  • omnichannel/agents/available
  • omnichannel/contact
  • omnichannel/contact.search
  • omnichannel/contacts
  • omnichannel/contacts.update
  • omnichannel/contacts.conflicts
  • omnichannel/contacts.get
  • omnichannel/contacts.search
  • omnichannel/contacts.channels
  • omnichannel/contacts.history
  • omnichannel/contacts.checkExistence
  • livechat/analytics/agent-overview
  • livechat/analytics/overview
  • livechat/config chore: migrate livechat/config, livechat/webhook.test, and livechat/integrations.settings to OpenAPI chained API pattern with AJV validation Rocket.Chat#39506
  • livechat/rooms
  • livechat/visitor/{token}
  • livechat/visitors.search
  • livechat/tags.list
  • livechat/tags/{tagId}
  • livechat/tags.getOne
  • livechat/priorities
  • livechat/priorities.list
  • livechat/priorities/{priorityId}
  • livechat/priority.getOne
  • livechat/business-hours
  • livechat/business-hours.list
  • livechat/business-hour
  • livechat/units
  • livechat/units.list
  • livechat/monitors
  • livechat/inquiries.queuedForUser
  • livechat/webhook.test chore: migrate livechat/config, livechat/webhook.test, and livechat/integrations.settings to OpenAPI chained API pattern with AJV validation Rocket.Chat#39506
  • livechat/integrations.settings chore: migrate livechat/config, livechat/webhook.test, and livechat/integrations.settings to OpenAPI chained API pattern with AJV validation Rocket.Chat#39506
  • livechat/custom.fields
  • livechat/message
  • livechat/messages.history/{rid}
  • omnichannel/integrations
  • omnichannel/integrations.list
  • canned-responses
  • canned-responses.get
  • canned-responses/{_id}
  • connector.extension.getRegistrationInfoByUserId
  • omnichannel/{rid}/request-transcript
  • omnichannel/agents/statistics
  • omnichannel/agents/statistics/{agentId}
  • omnichannel/resume-chat
  • omnichannel/transfer-chat
  • omnichannel/room.forward
  • omnichannel/room.close
  • omnichannel/room.hold
  • omnichannel/room.unhold
  • omnichannel/room.tags
  • omnichannel/room.tags.remove
  • omnichannel/room.info/{rid}
  • omnichannel/room.visitor.message
  • omnichannel/room.agent.message
  • omnichannel/room.messages/{rid}
  • omnichannel/room.checkExistence
  • omnichannel/room.history/{rid}
  • omnichannel/room.dual-history/{rid}
  • omnichannel/room.peek
  • omnichannel/room.queue
  • omnichannel/room.queueInfo/{rid}
  • omnichannel/room.queueStatistics
  • omnichannel/room.metrics/{rid}
  • omnichannel/room.metrics
  • omnichannel/room.tagStats
  • omnichannel/room.transferHistory/{rid}
  • omnichannel/visitor/{token}/departments
  • omnichannel/visitor/{token}/status
  • omnichannel/visitor/{token}/info
  • omnichannel/visitor/{token}/history
  • omnichannel/visitor/{token}/tags
  • voip/events
  • voip/managementServer/checkConnection
  • voip/callServer/checkConnection
  • voip/queues.getSummary
  • voip/queues.getQueuedCallsForThisExtension
  • voip/queues.getMembershipSubscription
  • voip/room
  • voip/room.close
  • voip/rooms
  • voip/room.join
  • voip/rooms.list
  • voip/rooms.history
  • voip/room.recording.start
  • voip/room.recording.stop
  • voip/room.participants
  • voip/room.participant.add
  • voip/room.participant.remove
  • voip/room.participant.mute
  • voip/room.participant.unmute
  • voip/room.participant.deafen
  • voip/room.participant.undeafen
  • voip/room.lock
  • voip/room.unlock
  • voip/room.info/{roomId}
  • voip/participant/info/{participantId}
  • voip/participant.muteAll
  • voip/participant.unmuteAll
  • voip/settings.get
  • voip/settings.update
  • voip/statistics
  • voip/transcripts/{roomId}
  • voip/call/{callId}/stats
  • voip/call/{callId}/start
  • voip/call/{callId}/end
  • voip/call/{callId}/transfer
  • voip/call/{callId}/mute
  • voip/call/{callId}/unmute
  • voip/call/{callId}/hold
  • voip/call/{callId}/unhold
  • voip/call/{callId}/join
  • voip/call/{callId}/participants
  • voip/call/{callId}/participant.add
  • voip/call/{callId}/participant.remove
  • voip/call/{callId}/participant.mute
  • voip/call/{callId}/participant.unmute
  • voip/call/{callId}/record.start
  • voip/call/{callId}/record.stop
  • voip/call/{callId}/stats.summary
  • voip/call/summary
  • voip/call/active
  • voip/call/history
  • voip/call/settings
  • voip/channel.create
  • voip/channel.list
  • voip/channel.info/{channelId}
  • voip/channel.update/{channelId}
  • voip/channel.delete/{channelId}
  • voip/channel.participants/{channelId}
  • voip/amqp/connect
  • voip/amqp/disconnect
  • voip/amqp/publish
  • voip/amqp/subscribe
  • voip/amqp/unsubscribe
  • voip/amqp/queues
  • voip/amqp/exchanges
  • voip/amqp/bind
  • voip/amqp/unbind
  • voip/amqp/consume
  • voip/amqp/ack
  • voip/amqp/nack
  • voip/amqp/prefetch
  • voip/amqp/metrics
  • voip/amqp/channels
  • omnichannel/{rid}/request-transcript
Miscellaneous (20 / 34 completed)
Notifications (3 / 7 completed)
Rooms (6 / 128 completed)
Settings (39 / 55 completed)
Statistics (0 / 15 completed)
User Management (11 / 54 completed)

Let me know if you'd like these grouped, categorized, or documented further.

📝 Secondary API Endpoints

These 2 endpoints are lower priority and can be migrated after core APIs: (calculating...)

Statistics (0 / 1 completed)
  • statistics.telemetry ⚠️ Blockedchore: Add OpenAPI Support to Statistics API Rocket.Chat#35692

    ⛔ Typia generates oneOf when it encounters a union type (|) in the interface.
    The issue with oneOf is that it requires exactly one schema to match—similar to XOR logic—so overlapping types fail validation.
    To fix this, we need Typia to generate anyOf instead of oneOf.

User Management (1 / 1 completed)
Notifications (7 / 7 completed)

📌 Important Notes

When migrating endpoints to the new OpenAPI + AJV pattern, keep these points in mind:

  1. No Change in Logic

    • The migration should only update the structure, validation, and documentation.
    • The core business logic, permissions, and side effects must remain exactly the same
  2. Error Response Codes

    • 400 (Bad Request) → Should be included for most endpoints with input validation.
    • 401 (Unauthorized) → Add only if the endpoint authRequired: true is included.
    • 403 (Forbidden) → Add only if specific permission checks are performed.
  3. Schema Validation

    • Use AJV for request/response validation.
    • Use Typia-generated $ref schemas where available instead of manually defining large object shapes.
  4. Centralized Error Validators

    • Use shared helpers like validateBadRequestErrorResponse instead of hard-coding error schemas.
    • This keeps error formats consistent across all endpoints.
  5. Route Definition Style

    • Use Route Method Chaining when defining multiple methods (.post(), .get(), etc.).
    • This is possible because ExtractRoutesFromAPI automatically groups routes under the same path in the type definitions.
  6. Optional Properties

    • If an endpoint doesn’t need permissionsRequired, omit it.
    • Always explicitly declare query or body in the route options — even if the endpoint has no parameters, set it to query: undefined or body: undefined.
    • Keep configs minimal — only include what’s necessary for that endpoint.
  7. No More rest-typings or Manual Typings

    • All request/response schemas are now defined directly inside the route definition file.
    • No schema definitions in rest-typings or other manual typing files — everything for an endpoint lives in one place for easier maintenance.
  8. Swagger Documentation

    • Confirm that both request and response schemas appear correctly in Swagger UI.
    • Check that example values are meaningful and match real data structures.

📖 Example: Migrating from Old Pattern to New Pattern

This example shows how to migrate from the legacy addRoute approach (with manual typings and deprecated validation)
to the new typed API definition pattern using:

  • API.v1.post() / .get() chaining (so multiple HTTP methods for the same path are merged in typings)
  • AJV for request & response validation
  • Typia $ref for shared model schemas
  • Automatic route typings with ExtractRoutesFromAPI (no more manual duplication)
  • Predefined error response validators instead of hard-coded schemas

Before – Old Pattern

// Route definition
API.v1.addRoute(
	'baz.foo',
	{
		authRequired: true,
		validateParams: ajv.compile<{ name: string }>({ // ❌ Deprecated
				type: 'object',
				properties: { name: { type: 'string' } },
				required: ['name'],
				additionalProperties: false,
			}),
		permissionsRequired: ['manage-foo'],
	},
	{
		async post() {
			const result = await updateFoo(this.bodyParams);
			return API.v1.success(result);
		},
	},
);

API.v1.addRoute(
	'baz.bar',
	{
		authRequired: true,
		validateParams: ajv.compile<{ name: string }>({ // ❌ Deprecated
				type: 'object',
				properties: { name: { type: 'string' } },
				required: ['name'],
				additionalProperties: false,
			}),
		permissionsRequired: ['manage-bar'],
	},
	{
		async get() {
			return API.v1.success(await getBar(this.queryParams.name));
		},
	},
);

// Manual typings in rest-typings
export type BazEndpoint = {
	POST: (params: FooParams) => FooResponse;
    GET: (params: BarParams) => BarResponse;
};

Problems with the old approach:

  1. No request/response schemas → can't generate Swagger/OpenAPI documentation automatically.
  2. validateParams is deprecated → doesn’t integrate with the new pattern.
  3. Manual typings in rest-typings → easy to forget or let them get out of sync.
  4. Hard-coded error handling → duplicated schemas everywhere.

After – New Pattern

const bazEndpoints = API.v1
	// POST /v1/baz.foo
	.post(
		'baz.foo',
		{
			authRequired: true,
			body: ajv.compile<{ name: string }>({
				type: 'object',
				properties: { name: { type: 'string' } },
				required: ['name'],
				additionalProperties: false,
			}),
			permissionsRequired: ['manage-foo'],
			response: {
				400: validateBadRequestErrorResponse, // Common for validation errors
				// 401: validateUnauthorizedErrorResponse, // Optional: if endpoint used with auth
				// 403: validateForbiddenErrorResponse,   // Optional: if specific permission checks exist
				200: ajv.compile<{ foo: IBaz }>({
					type: 'object',
					properties: {
						foo: { $ref: '#/components/schemas/IBaz' }, // ✅ Typia model reuse
						success: { type: 'boolean', enum: [true] },
					},
					required: ['foo', 'success'],
					additionalProperties: false,
				}),
			},
		},
		async function action() {
			const result = await updateFoo(this.bodyParams);
			return API.v1.success(result);
		},
	)
	// GET /v1/baz.bar
	.get(
		'baz.bar',
		{
			authRequired: true,
			query: ajv.compile<{ name: string }>({
				type: 'object',
				properties: { name: { type: 'string' } },
				required: ['name'],
				additionalProperties: false,
			}),
			permissionsRequired: ['manage-bar'],
			response: {
				400: validateBadRequestErrorResponse,
				// 401: validateUnauthorizedErrorResponse, // Optional
				// 403: validateForbiddenErrorResponse,   // Optional
				200: ajv.compile<{ foo: IBaz }>({
					type: 'object',
					properties: {
						bar: { $ref: '#/components/schemas/IBaz' },
						success: { type: 'boolean', enum: [true] },
					},
					required: ['bar', 'success'],
					additionalProperties: false,
				}),
			},
		},
		async function action() {
			return API.v1.success(await getBar(this.queryParams.name));
		},
	);

// ✅ Automatically generate typings for both GET and POST without duplication
export type BazEndpoints = ExtractRoutesFromAPI<typeof bazEndpoints>;

declare module '@rocket.chat/rest-typings' {
    // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
	interface Endpoints extends BazEndpoints {}
}

Key Improvements in the New Pattern

  1. Single source of truth for typings
    ExtractRoutesFromAPI pulls types directly from your post() / get() definitions — no more manual edits in rest-typings.

  2. Strong request validation with AJV
    Both body (POST) and query (GET) are validated against JSON schemas.

  3. Strong response validation
    Ensures the API always returns objects that match the documented shape.

  4. Reusable schemas with Typia
    $ref: '#/components/schemas/IBaz' links to a single IBaz schema used across APIs.

  5. Predefined error validators
    validateBadRequestErrorResponse, validateUnauthorizedErrorResponse, validateForbiddenErrorResponse replace repetitive error schemas.

  6. Chaining multiple methods on the same path
    Calling .post().get() on the same fooEndpoints ensures both methods are merged into one entry in the generated Endpoints interface.


🧪 Testing Plan

  • Ensure all migrated endpoints validate request and response schemas using AJV.
  • Confirm accurate documentation in Swagger UI for each endpoint.
  • Run integration tests to avoid regressions.

💡 Notes

  • This PR is for tracking and visibility; implementation PRs will be linked progressively.
  • Please feel free to suggest changes to prioritization.

@CLAassistant
Copy link

CLAassistant commented Jul 17, 2025

CLA assistant check
All committers have signed the CLA.

@Verifieddanny
Copy link

Hey @ahmed-n-abdeltwab , I'd like to take on the rooms.leave migration. I don't see any open PR for it. Can I go ahead?

@ahmed-n-abdeltwab
Copy link
Author

Hey @ahmed-n-abdeltwab , I'd like to take on the rooms.leave migration. I don't see any open PR for it. Can I go ahead?

Please go ahead, but mention this PR so I can mark it yours, because this way no one can duplicate the work

@ahmed-n-abdeltwab
Copy link
Author

ahmed-n-abdeltwab commented Feb 24, 2026

@Verifieddanny, once your PR is merged, could you please remove your old API like me?

@Verifieddanny
Copy link

Yes I will 🫡

@alchemycodess
Copy link

Hi @ahmed-n-abdeltwab , I see there's another PR (#39603) for chat.ignoreUser , should i continue with mine (#39587) or close it?

@ahmed-n-abdeltwab
Copy link
Author

Hi @ahmed-n-abdeltwab , I see there's another PR (#39603) for chat.ignoreUser , should i continue with mine (#39587) or close it?

We could merged the two PR together but it's recommended if everyone work on deferent API

@alchemycodess
Copy link

Hi @ahmed-n-abdeltwab , I'd like to migrate chat.getThreadMessages and chat.getDiscussions endpoints to the new OpenAPI + AJV pattern. Can I go ahead?

@ahmed-n-abdeltwab
Copy link
Author

Hi @ahmed-n-abdeltwab , I'd like to migrate chat.getThreadMessages and chat.getDiscussions endpoints to the new OpenAPI + AJV pattern. Can I go ahead?

ok

@NAME-ASHWANIYADAV
Copy link

Hi @ahmed-n-abdeltwab, I'd like to claim livechat/analytics/agent-overview and livechat/analytics/overview for migration. Can I go ahead?

@ahmed-n-abdeltwab
Copy link
Author

Hi @ahmed-n-abdeltwab, I'd like to claim livechat/analytics/agent-overview and livechat/analytics/overview for migration. Can I go ahead?

sure, go ahead

@amitb0ra
Copy link

Hi @ahmed-n-abdeltwab, I'd like to claim voip/call/{callId}/* for migration. Can I go ahead?

@ahmed-n-abdeltwab
Copy link
Author

ahmed-n-abdeltwab commented Mar 15, 2026

Hi @ahmed-n-abdeltwab, I'd like to claim voip/call/{callId}/* for migration. Can I go ahead?

The Omnichannel APIs is bottom of the list. We should probably migrate the other modules first

@amitb0ra
Copy link

Hi @ahmed-n-abdeltwab, I'd like to claim voip/call/{callId}/* for migration. Can I go ahead?

The Omnichannel APIs is bottom of the list. We should probably migrate the other modules first

Then can i go for users.create, users.register endpoints?

@ahmed-n-abdeltwab
Copy link
Author

Hi @ahmed-n-abdeltwab, I'd like to claim voip/call/{callId}/* for migration. Can I go ahead?

The Omnichannel APIs is bottom of the list. We should probably migrate the other modules first

Then can i go for users.create, users.register endpoints?

ok

@CodeMatrix1
Copy link

Hello ahmed-n-abdeltwab, just a heads up, My PRs on endpoints chat.search, chat.getDeletedMessages and chat.postMessage are ready to merge, I have resolved all comments etc,

thanks a lot for your spontaneity, really appreciate it!!!

hey @ahmed-n-abdeltwab , I have replied to your questions on my PRs, fyi, thanks a lot for the feedback btw!!

@alchemycodess
Copy link

Hi @ahmed-n-abdeltwab , I've opened PRs for the following migrations:
chat.getDiscussions - RocketChat/Rocket.Chat#39649
chat.getThreadMessages - RocketChat/Rocket.Chat#39654

@smirk-dev
Copy link

hi @ahmed-n-abdeltwab you have already reviewed pr RocketChat/Rocket.Chat#39625 (comment) and I have implemented your requested changes, so just leaving this here

@sezallagwal
Copy link

Hi @ahmed-n-abdeltwab
These PRs have been open for a while:
RocketChat/Rocket.Chat#39349
RocketChat/Rocket.Chat#39350

Could you please review them when you get a chance?

@Harxhit
Copy link

Harxhit commented Mar 16, 2026

Hi @ahmed-n-abdeltwab ,

I have completed the migration of two endpoints to the typed REST API structure:

  1. chat.syncThreadMessages
    refactor(chat): migrate chat.syncThreadMessages to typed REST endpoint Rocket.Chat#39669
  2. chat.getThreadsList
    refactor(chat): migrate chat.getThreadsList to typed REST endpoint Rocket.Chat#39655

Both endpoints are now aligned with the typed REST endpoint pattern used across the codebase. I have resolved the conflicts, and everything looks correct from my side.

Whenever you have time, could you please review them?
Thanks.

@ahmed-n-abdeltwab
Copy link
Author

ahmed-n-abdeltwab commented Mar 16, 2026

Hi @ahmed-n-abdeltwab ,

I have completed the migration of two endpoints to the typed REST API structure:

  1. chat.syncThreadMessages
    refactor(chat): migrate chat.syncThreadMessages to typed REST endpoint Rocket.Chat#39669
  2. chat.getThreadsList
    refactor(chat): migrate chat.getThreadsList to typed REST endpoint Rocket.Chat#39655

Both endpoints are now aligned with the typed REST endpoint pattern used across the codebase. I have resolved the conflicts, and everything looks correct from my side.

Whenever you have time, could you please review them? Thanks.

no it's not completed yet, you still need to complete the other steps

@smirk-dev
Copy link

hi @ahmed-n-abdeltwab you have already reviewed pr RocketChat/Rocket.Chat#39625 (comment) and I have implemented your requested changes, so just leaving this here

@ahmed-n-abdeltwab can you also checkout issue RocketChat/Rocket.Chat#38876

@Harxhit
Copy link

Harxhit commented Mar 16, 2026

Hi @ahmed-n-abdeltwab ,

I have completed the migration of two endpoints to the typed REST API structure:

  1. chat.syncThreadMessages
    refactor(chat): migrate chat.syncThreadMessages to typed REST endpoint Rocket.Chat#39669
  2. chat.getThreadsList
    refactor(chat): migrate chat.getThreadsList to typed REST endpoint Rocket.Chat#39655

Both endpoints are now aligned with the typed REST endpoint pattern used across the codebase. I have resolved the conflicts, and everything looks correct from my side.

Whenever you have time, could you please review them? Thanks.

no it's not completed yet, you still need to complete the other steps

Hi @ahmed-n-abdeltwab

Thanks for the feedback. Could you please clarify which remaining steps I should complete for these migrations?

So far I have:

  • Converted the routes to the typed API pattern (.get / .post chaining)
  • Added query/body validators with AJV
  • Added response validation (including success field)
  • Included 400 and 401 error validators
  • Verified the endpoint behavior locally

Please let me know what additional steps are still missing so I can complete them.

@CodeMatrix1
Copy link

@ahmed-n-abdeltwab can I claim users.delete and users.getUsernameSuggestion?, I see no PRs

@ahmed-n-abdeltwab
Copy link
Author

@ahmed-n-abdeltwab can I claim users.delete and users.getUsernameSuggestion?, I see no PRs

i suggest you should first compete what you have claim, until that you could move to the next API. make sure that's your old PRs are really ready and migrated completely

@ahmed-n-abdeltwab
Copy link
Author

ahmed-n-abdeltwab commented Mar 16, 2026

Hi @ahmed-n-abdeltwab

Thanks for the feedback. Could you please clarify which remaining steps I should complete for these migrations?

So far I have:

  • Converted the routes to the typed API pattern (.get / .post chaining)
  • Added query/body validators with AJV
  • Added response validation (including success field)
  • Included 400 and 401 error validators
  • Verified the endpoint behavior locally

Please let me know what additional steps are still missing so I can complete them.

read the Important Notes number 7, or take a look at the example

7- No More rest-typings or Manual Typings

  • All request/response schemas are now defined directly inside the route definition file.
  • No schema definitions in rest-typings or other manual typing files — everything for an endpoint lives in one place for easier maintenance.

@CodeMatrix1
Copy link

CodeMatrix1 commented Mar 16, 2026

@ahmed-n-abdeltwab can I claim users.delete and users.getUsernameSuggestion?, I see no PRs

i suggest you should first compete what you have claim, until that you could move to the next API. make sure that's your old PRs are really ready and migrated completely

like I have commented on what u hv asked on chat.getDeletedMessages and chat.postMessage, I do strongly believe my two PRs other than postMessage are ready to merge, i checked out the ui as well its working as expected

@Harxhit
Copy link

Harxhit commented Mar 17, 2026

Hi,@ahmed-n-abdeltwab

I have completed the migration of two endpoints to the typed REST API structure:
chat.syncMessages
RocketChat/Rocket.Chat#39682

Whenever you have time, could you please review them? If any changes needed I will fix it.

@Harxhit
Copy link

Harxhit commented Mar 17, 2026

Hi @ahmed-n-abdeltwab
Thanks for the feedback. Could you please clarify which remaining steps I should complete for these migrations?
So far I have:

  • Converted the routes to the typed API pattern (.get / .post chaining)
  • Added query/body validators with AJV
  • Added response validation (including success field)
  • Included 400 and 401 error validators
  • Verified the endpoint behavior locally

Please let me know what additional steps are still missing so I can complete them.

read the Important Notes number 7, or take a look at the example

7- No More rest-typings or Manual Typings

  • All request/response schemas are now defined directly inside the route definition file.
  • No schema definitions in rest-typings or other manual typing files — everything for an endpoint lives in one place for easier maintenance.

Hi @ahmed-n-abdeltwab,

I’ve addressed Note #7 — removed rest-typings and moved all schemas to the route files for both endpoints.

Updated PRs:

Please review when you have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.